import styled from '@emotion/styled';
import React, { useState, useEffect } from 'react';
import { LoadingOutlined, ExclamationCircleFilled } from '@ant-design/icons';
import { idCardOcr, bankCardOcr } from '@/api';
import { useBusiness } from '../Context/BusinessContext';
import { useTranslation } from 'react-i18next';
import { useCardCollect } from '../Context/CardCollectContext';

interface CardOCRProps {
	image: string;
	cardType: string;
	index: number;
	id: string;
	userRole: string;
	clientId: string;
}
interface BankCardOCRResult {
	bankName: string;
	cardNumber: string;
	cardType: string;
	validToDate: string;
}
interface IdCardOCRBackResult {
	issueAuthority: string;
	validPeriod: string;
}
interface IdCardOCRFaceResult {
	address: string;
	birthDate: string;
	ethnicity: string;
	idNumber: string;
	name: string;
	sex: string;
}
interface OCRResult {
	id: string;
	status: string;
	data: any;
	image: string;
}

const CardOCRContainer = styled.div`
	background-color: #ffffff;
`;

const OCRStatus = styled.div`
	text-align: center;
	padding-top: 6px;
	width: 261px;
	height: 36px;
	background: #f6f6f6;
	border-radius: 4px;
	margin-left: 25px;
	margin-top: 6px;
`;
const OCRProgress = styled.div`
	text-align: center;
	padding-top: 6px;
	width: 100%;
	height: 36px;
	border-radius: 4px;
	margin-top: 6px;
`;

const CardOCRBox = styled.div`
	width: 313px;
	height: 188px;
	margin-top: 14px;
`;

const CardOCRImg = styled.img`
	width: 100%;
	height: 100%;
`;

const CardOCRSpan = styled.span`
	font-size: 12px;
	font-weight: 400;
	color: #2a2a2a;
	line-height: 17px;
`;
const CardOCRButton = styled.button`
	font-size: 12px;
	font-weight: 400;
	color: #252b48;
	line-height: 17px;
	width: 72px;
	height: 26px;
	border-radius: 4px;
	border: 1px solid #e7e7e7;
	margin-left: 12px;
	cursor: pointer;
`;
const CardOCRDivider = styled.div`
	width: 312px;
	height: 1px;
	background: #f1f1f1;
	margin-top: 18px;
	margin-bottom: 18px;
`;

const CardOCRSpin = styled.span`
	font-size: 12px;
	font-weight: 400;
	color: #444444;
	line-height: 17px;
`;
const CardOCRFailed = styled.span`
	font-size: 12px;
	font-weight: 400;
	color: #da5a5a;
	line-height: 17px;
`;
const ResultBox = styled.div`
	margin-top: 14px;
`;
const ResultLabel = styled.span`
	display: inline-block;
	width: 75px;
	font-size: 12px;
	font-weight: 400;
	color: #666666;
	line-height: 17px;
`;
const ResultValue = styled.span`
	white-space: normal;
	max-width: 230px;
	background: #f6f6f6;
	border-radius: 4px;
	display: inline-block;
	font-size: 12px;
	font-weight: 400;
	color: #2d2d2d;
	line-height: 17px;
	padding: 8px;
`;

const CardOcrItem = (props: CardOCRProps) => {
	const { t } = useTranslation();
	const { image, cardType, index, id, clientId } = props;
	const [ocrStatus, setOcrStatus] = useState<string>(''); // progress | success | failed
	const [bankcardOcrResult, setBankcardOcrResult] = useState<BankCardOCRResult>({ bankName: '', cardNumber: '', cardType: '', validToDate: '' });
	const [idcardBackOcrResult, setIdcardBackOcrResult] = useState<IdCardOCRBackResult>({ issueAuthority: '', validPeriod: '' });
	const [idcardFaceOcrResult, setIdcardFaceOcrResult] = useState<IdCardOCRFaceResult>({ address: '', birthDate: '', ethnicity: '', idNumber: '', name: '', sex: '' });

	const { BusinessTaskMap } = useBusiness();
	const { autoOcr,idCardFront, idCardBack, bankCard, variableList, ocrResult, setOcrResult } = useCardCollect();

	useEffect(() => {
		const result = hasResult();
		if (result) {
			const { status, data } = result;
			setOcrStatus(status);
			if (cardType == 'idCard') {
				const { back, face } = data;
				if (back && back.data) {
					setIdcardBackOcrResult(back.data);
				} else if (face && face.data) {
					setIdcardFaceOcrResult(face.data);
				} else {
					setOcrStatus('failed');
				}
			} else {
				setBankcardOcrResult(data);
			}
		} else {
			// reset state
			setOcrStatus('');
			setBankcardOcrResult({ bankName: '', cardNumber: '', cardType: '', validToDate: '' });
			setIdcardBackOcrResult({ issueAuthority: '', validPeriod: '' });
			setIdcardFaceOcrResult({ address: '', birthDate: '', ethnicity: '', idNumber: '', name: '', sex: '' });
		}
		if (image && autoOcr() && !ocrResult()[image]) {
			setTimeout(() => {
				onOCR();
			}, 1000);
		}
	}, [image]);

	useEffect(() => {
		return () => {};
	}, []);

	const getBase64Image = (imageUrl: string) => {
		return new Promise(function (resolve, reject) {
			let xhr = new XMLHttpRequest();
			xhr.onload = function () {
				let reader = new FileReader();
				reader.onloadend = function () {
					let base64 = (reader.result as string) || ',';
					const sizeInBytes = 4 * Math.ceil(base64.length / 3) * 0.5624896334383812;
					console.log('MB: ' + sizeInBytes / 1024 / 1024);
					if (sizeInBytes / 1024 / 1024 >= 10) {
						// 压缩图片
						const img = new Image();
						img.setAttribute('crossOrigin', 'anonymous');
						img.src = base64;
						img.onload = function () {
							const scale = Math.min(1024 / img.height, 1024 / img.width);
							const canvas = document.createElement('canvas');
							canvas.width = 1024 * scale;
							canvas.height = 1024 * scale;
							const ctx = canvas.getContext('2d');
							if (ctx) {
								ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
								base64 = canvas.toDataURL('image/jpeg', 1.0);
								resolve(base64);
							} else {
								reject('context is null');
							}
						};
					} else {
						resolve(base64);
					}
				};
				reader.readAsDataURL(xhr.response);
			};
			xhr.addEventListener('error', err => {
				console.error('download image error : ', err);
				reject(err);
			});
			xhr.open('GET', imageUrl);
			xhr.responseType = 'blob';
			xhr.send();
		});
	};

	const onOCR = async () => {
		if (ocrStatus === 'progress') return;
		setOcrStatus('progress');
		updateResult('failed', {}, image);
		let result = {} as any;
		let done = false;
		let side = index == 0 ? 'face' : 'back';
		const type = cardType == 'idCard' ? 'idcard' : 'bankcard';
		try {
			const base64 = (await getBase64Image(image.replace(/^(http:\/\/)/, 'https://'))) as string;
			const resp = cardType == 'idCard' ? await idCardOcr(null, base64.split(',')[1]) : await bankCardOcr(null, base64.split(',')[1]);
			console.log('ocr result : ', resp);
			const { status, data } = resp;
			if (status == 200 && data && data.data) {
				if (cardType == 'idCard') {
					const { back, face } = data.data;
					if (back && back.data && index == 1) {
						setIdcardBackOcrResult(back.data);
						result = { ...back.data };
						done = true;
						side = 'back';
					} else if (face && face.data && index == 0) {
						setIdcardFaceOcrResult(face.data);
						result = { ...face.data };
						done = true;
						side = 'face';
					} else {
						setOcrStatus('failed');
					}
				} else {
					setBankcardOcrResult(data.data);
					result = { ...data.data };
					done = true;
					side = 'face';
				}
				if (done) {
					setOcrStatus('success');
					updateResult('success', data.data, image);
				}
			} else {
				setOcrStatus('failed');
				result = { error: status };
				updateResult('failed', {}, image);
			}
		} catch (error) {
			console.error('ocr error : ', error);
			const { data = { message: '' } } = error as any;
			result = { error: data?.message || '' };
			setOcrStatus('failed');
			updateResult('failed', {}, image);
		} finally {
			// 发送ocr识别结果 {type: enum('idcard','bankcard'),result:object(), side： back | face}
			const variable = getVariableValue(type, side, result)
			ivcs.agent.sendOcrRecord(
				{ type: type, result: {...result, variable: variable}, status: done ? 'done' : 'failed', side: side },
				clientId || 'all', // 访客id
				(resp: any) => {
					console.log(resp);
				},
				(error: any) => {
					console.log(error);
				}
			);
			// 缓存ocr已识别结果
			const value = {...ocrResult()}
			value[image] = true;
			setOcrResult(value)
		}
	};

	const getVariableValue = (type: string, side: string, data: any) => {
		let result: any [] = [];
		let list = [];
		if (type === 'idcard') {
			if (side === 'face') {
				list = idCardFront().filter((item: any) => !!item.parameterName);
			} else {
				list = idCardBack().filter((item: any) => !!item.parameterName);
			}
		} else {
			list = bankCard().filter((item: any) => !!item.parameterName);
		}
		list.map((item: any) => {
			let value = data[item.fieldName]
			if (value) {
				const id = item.parameterName.split('-')[3];
				const variable = variableList().find(item => item.id == id)
				if (variable.type === 'numeric') {
					value = Number(value) || '';
				}
				result.push({...variable, value: value});
			}
		})
		return result;
	};

	const updateResult = (status: string, data: any, image: string) => {
		let found = false;
		for (const item of BusinessTaskMap.OcrResultList) {
			if (item.id == `${id}_${index}`) {
				item.status = status;
				item.data = data;
				item.image = image;
				found = true;
				break;
			}
		}
		if (!found) {
			const add = { id: `${id}_${index}`, status: status, data: data, image: image };
			BusinessTaskMap.OcrResultList.push(add);
		}
	};

	const hasResult = () => {
		let found: OCRResult | null = null;
		for (const item of BusinessTaskMap.OcrResultList) {
			if (item.id == `${id}_${index}` && item.image == image) {
				found = item;
				break;
			}
		}
		return found;
	};

	const ocrProgress = (
		<OCRProgress>
			<LoadingOutlined style={{ fontSize: '12px', marginRight: '6px' }} />
			<CardOCRSpin>{t('ocr-recognitioning')}</CardOCRSpin>
		</OCRProgress>
	);
	const ocrFailed = (
		<OCRStatus>
			<ExclamationCircleFilled style={{ fontSize: '12px', color: '#f00', marginRight: '6px' }} />
			<CardOCRFailed>{t('ocr-recognition-failed')}</CardOCRFailed>
		</OCRStatus>
	);

	const ocrIdCardFront = (
		<ResultBox>
			<p>
				<ResultLabel>{t('id-number')}</ResultLabel>
				<ResultValue>{idcardFaceOcrResult.idNumber}</ResultValue>
			</p>
			<p>
				<ResultLabel>{t('name')}</ResultLabel>
				<ResultValue>{idcardFaceOcrResult.name}</ResultValue>
			</p>
			<p>
				<ResultLabel>{t('gender')}</ResultLabel>
				<ResultValue>{idcardFaceOcrResult.sex}</ResultValue>
			</p>
			<p>
				<ResultLabel>{t('nationality')}</ResultLabel>
				<ResultValue>{idcardFaceOcrResult.ethnicity}</ResultValue>
			</p>
			<p>
				<ResultLabel>{t('birth-date')}</ResultLabel>
				<ResultValue>{idcardFaceOcrResult.birthDate}</ResultValue>
			</p>
			<p style={{ whiteSpace: 'nowrap' }}>
				<ResultLabel>{t('address')}</ResultLabel>
				<ResultValue>{idcardFaceOcrResult.address}</ResultValue>
			</p>
		</ResultBox>
	);
	const ocrIdCardBack = (
		<ResultBox>
			<p>
				<ResultLabel>{t('issuing-authority')}</ResultLabel>
				<ResultValue>{idcardBackOcrResult.issueAuthority}</ResultValue>
			</p>
			<p>
				<ResultLabel>{t('effective-date')}</ResultLabel>
				<ResultValue>{idcardBackOcrResult.validPeriod}</ResultValue>
			</p>
		</ResultBox>
	);
	const ocrBankCard = (
		<ResultBox>
			<p>
				<ResultLabel>{t('card-type')}</ResultLabel>
				<ResultValue>{bankcardOcrResult.cardType}</ResultValue>
			</p>
			<p>
				<ResultLabel>{t('card-number')}</ResultLabel>
				<ResultValue>{bankcardOcrResult.cardNumber}</ResultValue>
			</p>
			<p>
				<ResultLabel>{t('bank')}</ResultLabel>
				<ResultValue>{bankcardOcrResult.bankName}</ResultValue>
			</p>
			<p>
				<ResultLabel>{t('validity-period')}</ResultLabel>
				<ResultValue>{bankcardOcrResult.validToDate}</ResultValue>
			</p>
		</ResultBox>
	);
	return (
		<CardOCRContainer>
			{index > 0 && <CardOCRDivider></CardOCRDivider>}
			<CardOCRSpan>{cardType == 'idCard' ? (index == 0 ? t('id-card-face') : t('id-card-back')) : t('bank-card-photo')}</CardOCRSpan>
			{/* <CardOCRButton onClick={onOCR}>{t('ocr-recognition')}</CardOCRButton> */}

			<CardOCRBox>
				<CardOCRImg src={image}></CardOCRImg>
			</CardOCRBox>
			{ocrStatus == 'progress' && ocrProgress}
			{ocrStatus == 'failed' && ocrFailed}
			{ocrStatus == 'success' && cardType == 'idCard' && index == 0 && ocrIdCardFront}
			{ocrStatus == 'success' && cardType == 'idCard' && index == 1 && ocrIdCardBack}
			{ocrStatus == 'success' && cardType == 'bankCard' && ocrBankCard}
		</CardOCRContainer>
	);
};

export default CardOcrItem;
